
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System;

namespace Galplay {

  public class ImageManager : MonoBehaviour {
    [Tooltip("背景图片")]
    public Image _backgroundImage;
    [Tooltip("用于创建的Prefab")]
    public GameObject prefab;
    [Tooltip("游戏原本的分辨率，用来调整项目")]
    public Vector2 originSize;

    private float heightScaleFactor; // 高度缩放因子

    private Dictionary<int, ImageSlot> _imageSlots;

    private GameManager GM => GameManager.Instance;

    private void Awake() {
      _imageSlots = new Dictionary<int, ImageSlot>();

    }

    void Start() {
      SetResolution(originSize);
    }

    /// <summary>
    /// 获取指定位置的ImageSlot，确保Image已创建
    /// </summary>
    private ImageSlot UseSlot(int slot) {
      if (!_imageSlots.ContainsKey(slot)) {
        var go = Instantiate(prefab, transform);
        // 设置层级顺序（slot越大显示在越上层）
        go.transform.SetSiblingIndex(slot);

        _imageSlots[slot] = go.GetComponent<ImageSlot>();
        _imageSlots[slot].index = slot;
      }

      _imageSlots[slot].Show();
      return _imageSlots[slot];
    }

    private ImageSlot GetSlot(int slot) {
      if (!_imageSlots.ContainsKey(slot)) {
        return null;
      } else {
        return _imageSlots[slot];
      }
    }

    /// <summary>
    /// 设置指定位置的图片
    /// </summary>
    /// <param name="slot">位置索引（0=背景）</param>
    /// <param name="sprite">要设置的图片</param>
    /// <param name="x">X坐标</param>
    /// <param name="y">Y坐标</param>
    /// <summary>
    /// 设置指定位置的图片
    /// </summary>
    public void SetPicture(int slot, Vector2Int point, Sprite sprite) {
      var imageSlot = UseSlot(slot);
      var img = imageSlot.image;

      img.sprite = sprite;
      img.SetNativeSize();
      img.rectTransform.localScale = new Vector2(heightScaleFactor, heightScaleFactor);
      img.rectTransform.anchoredPosition = MapPos(point);

      img.gameObject.SetActive(true);
    }

    /// <summary>
    /// 这个项目设置一个Flash，在此之前，应该确保项目已经使用
    /// </summary>
    internal void SetFlash(int slot, float enable) {
      GetSlot(slot)?.SetFlash(enable);
    }

    /// <summary>
    /// 隐藏指定位置的图片
    /// </summary>
    /// <param name="slot">位置索引</param>
    public void HidePicture(int slot) {
      GetSlot(slot)?.gameObject.SetActive(false);
    }

    /// <summary>
    /// 隐藏指定范围内的图片
    /// </summary>
    /// <param name="from">起始索引</param>
    /// <param name="to">结束索引</param>
    public void HidePicture(int from, int to) {
      for (int i = from; i <= to; i++) {
        HidePicture(i);
      }
    }

    internal void SetPicture(int slot, Vector2Int point, string relativePath) {
      // 从GameResources中载入
      var file = GM.Game.GetAssetFile(relativePath);
      if (file == null) { return; }
      GameResources.Instance.LoadImageAsync(file, (sprite) => {
        if (sprite != null) {
          SetPicture(slot, point, sprite);
        } else {
          Debuger.LogError($"{relativePath} load failed!");
        }
      });
    }

    public void SetResolution(Vector2 originResolution) {
      originSize = originResolution;
      // 计算以高度为基准的缩放因子
      heightScaleFactor = Screen.height / originSize.y;
    }

    /// <summary>
    /// 获取内容在水平方向上的起始X坐标（用于居中）
    /// </summary>
    public float GetStartX() {
      // 计算缩放后的内容宽度
      float scaledWidth = originSize.x * heightScaleFactor;

      // 如果缩放后宽度小于屏幕宽度，则居中处理
      if (scaledWidth < Screen.width) {
        return (Screen.width - scaledWidth) * 0.5f;
      }

      // 如果缩放后内容比屏幕宽，则从0开始（左对齐）
      return 0f;
    }

    /// <summary>
    /// 将原始分辨率中的坐标映射到当前屏幕分辨率
    /// </summary>
    /// <param name="pos">原始分辨率中的坐标</param>
    /// <returns>映射后的新坐标</returns>
    public Vector2 MapPos(Vector2Int pos) {
      // 应用高度缩放
      float scaledX = pos.x * heightScaleFactor;
      float scaledY = pos.y * heightScaleFactor;

      // 调整X坐标使其居中
      scaledX += GetStartX();

      // 反转Y轴（Unity坐标系Y轴向下为正，通常原始坐标Y轴向上为正）
      return new Vector2(scaledX, -scaledY);
    }

    /// <summary>
    /// 将原始分辨率中的矩形映射到当前屏幕分辨率
    /// </summary>
    public Rect MapRect(Rect originRect) {
      Vector2 pos = MapPos(new Vector2Int((int)originRect.x, (int)originRect.y));
      float width = originRect.width * heightScaleFactor;
      float height = originRect.height * heightScaleFactor;

      return new Rect(pos.x, pos.y - height, width, height);
    }

    internal void HideAll() {
      foreach (KeyValuePair<int, ImageSlot> pair in _imageSlots) {
        pair.Value.Hide();
      }
    }

    internal void SetBg(string relativePath) {
      // 从GameResources中载入
      var file = GM.Game.GetAssetFile(relativePath);
      if (file == null) { return; }
      GameResources.Instance.LoadImageAsync(file, (sprite) => {
        if (sprite != null) {
          _backgroundImage.sprite = sprite;
        } else {
          Debuger.LogError($"{file.Path} load failed!");
        }
      });
    }
  }
}